/* route.h - routing table */

/* Copyright 2001-2005 Wind River Systems, Inc. */

/*
 * Copyright (c) 1980, 1986, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the University of
 *	California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)route.h	8.4 (Berkeley) 1/9/95
 * $FreeBSD: src/sys/net/route.h,v 1.36.2.5 2002/02/01 11:48:01 ru Exp $
 */

/*
modification history
--------------------
01z,19may05,rp   added RTM_ADDRINFO
01y,01mar05,niq  Include in6.h
01x,24feb05,spm  removed unneeded route format storage (SPR #100995)
01w,24feb05,spm  performance updates and code cleanup (SPR #100995)
01v,08feb05,vvv  _KERNEL cleanup
01u,17sep04,niq  Scale out routing sockets
01t,23aug04,rp   merged from COMP_WN_IPV6_BASE6_ITER5_TO_UNIFIED_PRE_MERGE
01s,28may04,niq  Merging from base6 label POST_ITER5_FRZ16_REBASE (ver
                 /main/vdt/base6_itn5_networking-int/2)
01r,06dec03,niq  Add the RTF_PRIMARY flag
01q,24nov03,vvv  updated for RTP support
01p,20nov03,niq  Remove copyright_wrs.h file inclusion
01o,10nov03,cdw  Rebase from base6 iteration 1 view
01n,04nov03,rlm  Ran batch header path update for header re-org.
01m,03nov03,rlm  Removed wrn/coreip/ prefix from #includes for header re-org.
01l,27sep03,vvv  moved RTFREE out of #ifdef _KERNEL
01k,23sep03,asr  Moved the #include <route/ipRouteLib.h> outside of #ifdef _KERNEL 
01j,06aug03,niq  Merge from Accordion into Base6 Iteration 1 branch
01i,10jun03,vvv  include netVersion.h
01h,01feb03,pas  merge from FreeBSD 4.7 - added rt_getifa(),
                 rt_ifannouncemsg(), rtrequest1()
01g,05sep02,hsh  add cplusplus protection
01f,16may02,ant  field rmx_filler[4] in the struct rt_metrics expand to 
		 rmx_filler[5]. New definitions rt_mod and RTF_MGMT
01e,11mar02,ham  reverted previous checkin 01d
01d,27feb02,nee  extending the rt_metrics for rip
01c,02feb02,ham  changed for tornado build.
01b,19dec01,nee  Adding multipath capability
01a,08sep01,qli  1st round of porting
*/


#ifndef _NET_ROUTE_H_
#define _NET_ROUTE_H_

#include <sys/socket.h>

#ifdef __cplusplus
extern "C" {
#endif

#include <netVersion.h>

/*
 * Kernel resident routing tables.
 *
 * The routing tables are initialized when interface addresses
 * are set by making entries for all directly connected interfaces.
 */

/*
 * We distinguish between routes to hosts and routes to networks,
 * preferring the former if available.  For each route we infer
 * the interface to use from the gateway address supplied when
 * the route was entered.  Routes that forward packets through
 * gateways are marked so that the output routines know to address the
 * gateway rather than the ultimate destination.
 */

/*
 * Following structure necessary for 4.3 compatibility;
 * We should eventually move it to a compat file.
 */
struct ortentry {
	u_long	ort_hash;		/* to speed lookups */
	struct	sockaddr ort_dst;	/* key */
	struct	sockaddr ort_gateway;	/* value */
	short	ort_flags;		/* up/down?, host/net */
	short	ort_refcnt;		/* # held references */
	u_long	ort_use;			/* raw # packets forwarded */
	struct	ifnet *ort_ifp;		/* the answer: interface to use */
};

/*
 * These numbers are used by reliable protocols for determining
 * retransmission behavior and are included in the routing structure.
 */
struct rt_metrics {
	u_long	rmx_locks;	/* Kernel must leave these values alone */
	u_long	rmx_mtu;	/* MTU for this path */
	u_long	rmx_hopcount;	/* max hops expected */
	u_long	rmx_expire;	/* lifetime for route, e.g. redirect */
	u_long	rmx_recvpipe;	/* inbound delay-bandwidth product */
	u_long	rmx_sendpipe;	/* outbound delay-bandwidth product */
	u_long	rmx_ssthresh;	/* outbound gateway buffer limit */
	u_long	rmx_rtt;	/* estimated round trip time */
	u_long	rmx_rttvar;	/* estimated rtt variance */
	u_long	rmx_pksent;	/* packets sent using this route */
	u_long  rmx_filler[5];  /* will be used for T/TCP later */
                                /* the last field is used for storing
                                   of the last modification of the route */

        /* Additional WRN metrics for routing protocols */

        long    value1;
        long    value2;
        long    value3;
        long    value4;
        long    value5;
        long    routeTag;
        u_long  weight;
};

/* RTM entry header - pointed to by RIB node */
struct routeHdr
    {
    struct sockaddr *   pDstAddr;       /* Route destination */
    struct sockaddr *   pNetmask;       /* Route netmask */
    struct rtentry *    pFirstRoute;    /* Initial route entry (weight) */
    struct rtentry *    pFirstLexRoute; /* Initial route entry (SNMP) */
    unsigned short      routeHdrFlags;  /* Route header flags */
    UCHAR 		routeCount; 	/* Number of shared route entries */
    };

/* 
 * Generic route entry to store route information.
 * The fields are layed out based on the cache locality consideration.
 * Please do not move them around merely for aesthetic purposes.
 */

struct mbuf;

struct rtentry 
    {
    struct routeHdr *    pRtmHdr;	/* RTM header */
    struct sockaddr *	rt_gateway;	/* Next-hop gateway */ 
    struct rtentry *	rt_gwroute;	/* Pointer to gateway entry */
    struct ifnet * 	rt_ifp;		/* Which interface to use */
    ULONG		rt_flags;	/* Route flags: Uses RTF_ values: */
    long 		rt_refcnt;	/* # of held references */
    caddr_t		rt_llinfo;	/* pointer to link level info cache */
    struct ifaddr *	rt_ifa;		/* Interface address */
    struct rtentry *	rt_parent;   	/* cloning parent of this route */
    ULONG  		routeTos; 	/* Type-of-service information */
    struct rt_metrics 	rt_rmx;		/* Route metrics */
    struct sockaddr *	rt_genmask;	/* For generation of cloned routes */
    int   (*rt_output) 	(struct ifnet *, struct mbuf *, struct sockaddr *, 
			 struct rtentry *);
				    	/* output routine for this (rt,if) */
    void    *		rt_filler2;    	/* more filler */
    struct rtentry *	pNextRoute;	/* Additional route entry (weight) */
    struct rtentry *	pNextLexRoute; 	/* Additional route entry (SNMP) */
    void *		pRibNode;	/* Pointer to RIB node */
    ULONG  		routeOwner; 	/* Route ownership information */ 
    ULONG 		rtmFlags;	/* Proxy ARP entry or not. See below */
      					/* for the values */
    };
#define rt_use 		rt_rmx.rmx_pksent
#define rt_mod 		rt_rmx.rmx_filler[4]

/* 
 * The following macros SHOULD be used to access the fields of the rtentry
 * structures. Directly accessing fields might not be portable
 */

#define rt_key(r) 	((r)->pRtmHdr->pDstAddr)
#define rt_mask(r) 	((r)->pRtmHdr->pNetmask)

/* 
 * This constant defines the weight for every interface route installed by
 * the system. This value should be the lowest possible weight so that the
 * system interface route is always preferred over any other interface routes
 * which a routing protocol may create. This priority is necessary since
 * the system's interface route generates all ARP/ND entries through cloning,
 * so it must be the first entry in the weighted list if duplicates exist.
 * Without this value, the system route is often still the first entry in the
 * list since the RIP interface routes (and any others) are added with the
 * the default weight value. However, if any routing protocols install routes
 * with a weight lower than the default, then the system's interface route
 * would no longer be first, so it is assigned the lowest possible weight.
 */

#define INTERFACE_ROUTE_WEIGHT	1

/* 
 * macros for getting and setting tos values in sockaddr_in 
 * structures. A new sockaddr structure is defined for this
 * purpose as shown below.
 */
struct sockaddr_rt {
    u_char	srt_len;
    u_char	srt_family;
    u_char	srt_proto;
    u_char	srt_tos;          
    ULONG	srt_addr;
    char		sin_zero[8];
    };

#define TOS_GET(pSockaddr) (((struct sockaddr_rt *)(pSockaddr))->srt_tos)

#define TOS_SET(pSockaddr, tosVal) \
    (((struct sockaddr_rt *)(pSockaddr))->srt_tos = tosVal)

#define RT_PROTO_GET(pSockaddr) (((struct sockaddr_rt *)(pSockaddr))->srt_proto)

#define RT_PROTO_SET(pSockaddr, proto) \
    (((struct sockaddr_rt *)(pSockaddr))->srt_proto = proto)

/*
 * Set the route tos and proto from the route in the provided dst address
 * Saves the original Tos and Proto value if pointers are provided
 */
#define SET_TOS_AND_PROTO(dst, rt) \
	do { \
	    TOS_SET (dst, ROUTE_TOS (rt)); \
	    RT_PROTO_SET (dst, ROUTE_PROTO (rt)); \
	} while (0)

/*
 * Reset the original route tos and proto values in the route's dst address
 */
#define RESET_TOS_AND_PROTO(dst) \
	do { \
	    TOS_SET (dst, 0); \
	    RT_PROTO_SET (dst, 0); \
	} while (0)

/*
 * A route consists of a destination address and a reference
 * to a routing entry.  These are often held by protocols
 * in their control blocks, e.g. inpcb.
 */
struct route {
	struct	rtentry *ro_rt;
	struct	sockaddr ro_dst;
};


#ifdef ROUTER_STACK
/*
 * This expanded "gateway" structure contains the address of the next-hop
 * router and all the new metrics for a route, as well as the protocol
 * identifier which created it. The RTM_GETALL routing socket message
 * contains a list of these structures.
 *
 * NOTE: don't change the position of the gate_addr field. It is designed to
 * overlay the sockaddr_in(6) structures.
 */

struct sockaddr_gate
    {
    u_char         gate_len;
    u_char         gate_family;
    u_char         routeProto;
    u_char         weight;
    u_long         gate_addr;
    long           value1;
    long           value2;
    long           value3;
    long           value4;
    long           value5;
    long           routeTag;
    long           routeTos;
    struct sockaddr * ifa;
    struct sockaddr * ifp;
    };

#ifdef INET6
#include <netinet/in.h>	
#include <netinet6/in6.h>	/* For in6_addr */

struct sockaddr_gate6
    {
    u_char         gate_len;
    u_char         gate_family;
    u_char         routeProto;
    u_char         weight;
    long           value1;
    struct in6_addr gate6_addr;
    long           value2;
    long           value3;
    long           value4;
    long           value5;
    long           routeTag;
    long           routeTos;
    struct sockaddr * ifa;
    struct sockaddr * ifp;
    };
#endif /* INET6 */
#endif /* ROUTER_STACK */



/*
 * rmx_rtt and rmx_rttvar are stored as microseconds;
 * RTTTOPRHZ(rtt) converts to a value suitable for use
 * by a protocol slowtimo counter.
 */
#define	RTM_RTTUNIT	1000000	/* units for rtt, rttvar, as units per sec */
#define	RTTTOPRHZ(r)	((r) / (RTM_RTTUNIT / PR_SLOWHZ))

/*
 * XXX kernel function pointer `rt_output' is visible to applications.
 */

/* Values for rt_flags */
#define RTF_UP		0x1		/* route usable */
#define RTF_GATEWAY	0x2		/* destination is a gateway */
#define RTF_HOST		0x4		/* host entry (net otherwise) */
#define RTF_REJECT	0x8		/* host or net unreachable */

#define RTF_DYNAMIC	0x10		/* created dynamically (by redirect) */
#define RTF_MODIFIED	0x20		/* modified dynamically (by redirect)*/
#define RTF_DONE		0x40		/* message confirmed */
#define RTF_NO_MSGS	RTF_DONE	/* tells the RTM to not generate
					 * routing messages
					 */
#define RTF_DELCLONE	0x80		/* delete cloned route */
#define RTF_INTF_ROUTE	RTF_DELCLONE	/* Used to indicate to rtrequest that
					 * this is an interface route. */

#define RTF_CLONING	0x100		/* generate new routes on use */
#define RTF_XRESOLVE	0x200		/* external daemon resolves name */
#define RTF_LLINFO	0x400		/* generated by link layer (e.g. ARP)*/
#define RTF_STATIC	0x800		/* manually added */

#define RTF_BLACKHOLE	0x1000		/* just discard pkts (during updates)*/
#define RTF_MGMT		0x2000          /* modified by management proto */
#define RTF_PROTO2	0x4000		/* protocol specific routing flag */
#define RTF_PROTO1	0x8000		/* protocol specific routing flag */

#define RTF_PRCLONING	0x10000		/* protocol requires cloning */
#define RTF_WASCLONED	0x20000		/* route generated through cloning */
#define RTF_PROTO3	0x40000		/* protocol specific routing flag */
#define RTPRF_OURS	RTF_PROTO3	/* set on routes we manage */
/*			0x80000		   unused */

#define RTF_PINNED	0x100000	/* future use */
#define RTF_LOCAL	0x200000 	/* route represents a local address */
#define RTF_BROADCAST	0x400000	/* route represents a bcast address */
#define RTF_MULTICAST	0x800000	/* route represents a mcast address */
					/* 0x1000000 and up unassigned */
#define RTF_LLNOTAVAIL	0x1000000	/* Link layer not available for eg. */
					/* if the interface is down */
#define RTF_PRIMARY  	0x2000000	/* Primary route -used for forwarding*/


/*
 * Routing statistics.
 */
struct	rtstat {
	short	rts_badredirect;	/* bogus redirect calls */
	short	rts_dynamic;		/* routes created by redirects */
	short	rts_newgateway;		/* routes modified by redirects */
	short	rts_unreach;		/* lookups which failed */
	short	rts_wildcard;		/* lookups satisfied by a wildcard */
};
/*
 * Structures for routing messages.
 */
struct rt_msghdr {
	u_short	rtm_msglen;	/* to skip over non-understood messages */
	u_char	rtm_version;	/* future binary compatibility */
	u_char	rtm_type;	/* message type */
	u_short	rtm_index;	/* index for associated ifp */
	int	rtm_flags;	/* flags, incl. kern & message, e.g. DONE */
	int	rtm_addrs;	/* bitmask identifying sockaddrs in msg */
	pid_t	rtm_pid;	/* identify sender */
	int	rtm_seq;	/* for sender to identify action */
	int	rtm_errno;	/* why failed */
	int	rtm_use;	/* from rtentry */
	u_long	rtm_inits;	/* which metrics we are initializing */
	struct	rt_metrics rtm_rmx; /* metrics themselves */
};

#define RTM_VERSION	5	/* Up the ante and ignore older versions */

/*
 * Message types. The message numbers should be continous as their
 * values are used as array indices
 */
#define RTM_ADD		0x1	/* Add Route */
#define RTM_DELETE	0x2	/* Delete Route */
#define RTM_CHANGE	0x3	/* Change Metrics or flags */
#define RTM_GET		0x4	/* Report Metrics */
#define RTM_LOSING	0x5	/* Kernel Suspects Partitioning */
#define RTM_REDIRECT	0x6	/* Told to use different route */
#define RTM_MISS		0x7	/* Lookup failed on this address */
#define RTM_LOCK		0x8	/* fix specified metrics */
#define RTM_OLDADD	0x9	/* caused by SIOCADDRT */
#define RTM_OLDDEL	0xa	/* caused by SIOCDELRT */
#define RTM_RESOLVE	0xb	/* req to resolve dst to LL addr */
#define RTM_NEWADDR	0xc	/* address being added to iface */
#define RTM_DELADDR	0xd	/* address being removed from iface */
#define RTM_IFINFO	0xe	/* iface going up/down etc. */
#define RTM_NEWMADDR	0xf	/* mcast group membership being added to if */
#define RTM_DELMADDR	0x10	/* mcast group membership being deleted */
#define RTM_IFANNOUNCE	0x11	/* iface arrival/departure */

#ifdef ROUTER_STACK

/* New WRN messages */

#define RTM_NEWCHANGE	0x12	/* Change gateway of duplicate route */
#define RTM_NEWGET	0x13	/* Find any route with gateway */
#define RTM_GETALL	0x14	/* Get IP route to dst and any duplicates */
#endif /* ROUTER_STACK */

#define RTM_NEWIPROUTE	0x15	/* Replacement for deleted primary IP route */
#define RTM_OLDIPROUTE	0x16	/* Demoted IP route replaced with new entry */

#ifdef ROUTER_STACK
/* Backward compatibility messages. Will go away in the next release */
    
#define RTM_ADDEXTRA	0x17	/* Duplicate route added */
#define RTM_DELEXTRA	0x18	/* Duplicate route deleted */
#endif /* ROUTER_STACK */

#define RTM_ADDRINFO	0x19	/* change address flags */
/*
 * Bitmask values for rtm_inits and rmx_locks.
 */
#define RTV_MTU		0x1	/* init or lock _mtu */
#define RTV_HOPCOUNT	0x2	/* init or lock _hopcount */
#define RTV_EXPIRE	0x4	/* init or lock _expire */
#define RTV_RPIPE	0x8	/* init or lock _recvpipe */
#define RTV_SPIPE	0x10	/* init or lock _sendpipe */
#define RTV_SSTHRESH	0x20	/* init or lock _ssthresh */
#define RTV_RTT		0x40	/* init or lock _rtt */
#define RTV_RTTVAR	0x80	/* init or lock _rttvar */

/* New flag values for additional metrics */

#define RTV_VALUE1      0x100   /* assign or lock first additional metric */
#define RTV_VALUE2      0x200   /* assign or lock second additional metric */
#define RTV_VALUE3      0x400   /* assign or lock third additional metric */
#define RTV_VALUE4      0x800   /* assign or lock fourth additional metric */
#define RTV_VALUE5      0x1000  /* assign or lock fifth additional metric */
#define RTV_ROUTETAG    0x2000  /* assign or lock route tag value */
#define RTV_WEIGHT      0x4000  /* assign or lock administrative weight */

/*
 * Bitmask values for rtm_addrs.
 */
#define RTA_DST		0x1	/* destination sockaddr present */
#define RTA_GATEWAY	0x2	/* gateway sockaddr present */
#define RTA_NETMASK	0x4	/* netmask sockaddr present */
#define RTA_GENMASK	0x8	/* cloning mask sockaddr present */
#define RTA_IFP		0x10	/* interface name sockaddr present */
#define RTA_IFA		0x20	/* interface addr sockaddr present */
#define RTA_AUTHOR	0x40	/* sockaddr for author of redirect */
#define RTA_BRD		0x80	/* for NEWADDR, broadcast or p-p dest addr */

/*
 * Index offsets for sockaddr array for alternate internal encoding.
 */
#define RTAX_DST		0	/* destination sockaddr present */
#define RTAX_GATEWAY	1	/* gateway sockaddr present */
#define RTAX_NETMASK	2	/* netmask sockaddr present */
#define RTAX_GENMASK	3	/* cloning mask sockaddr present */
#define RTAX_IFP		4	/* interface name sockaddr present */
#define RTAX_IFA		5	/* interface addr sockaddr present */
#define RTAX_AUTHOR	6	/* sockaddr for author of redirect */
#define RTAX_BRD		7	/* for NEWADDR, broadcast or p-p dest addr */
#define RTAX_MAX		8	/* size of array to allocate */

struct rt_addrinfo {
	int	rti_addrs;
	struct	sockaddr *rti_info[RTAX_MAX];
};

struct route_cb {
	int	ip_count;
	int	ip6_count;
	int	ipx_count;
	int	ns_count;
	int	any_count;
};

/*
 * This macro is called by users of RTM to release references to the 
 * route entry.
 * this macro will be called as RTFREE (rt)
 */

#ifdef FINEGRAIN_LOCKING_MODEL
#define	RTFREE(rt)	ipRouteUnlock (rt) 
#else
#define	RTFREE(rt)	_RTFREE (rt) 
#endif /* FINEGRAIN_LOCKING_MODEL */

#ifdef _WRS_KERNEL

#ifdef FINEGRAIN_LOCKING_MODEL
#define	RTLOCK(rt)	ipRouteLock (rt) 
#else
#define	RTLOCK(rt)	(RREFCNT (rt))++
#endif /* FINEGRAIN_LOCKING_MODEL */

#ifndef VIRTUAL_STACK
extern struct route_cb _route_cb;
#endif	/* VIRTUAL_STACK */

struct ifmultiaddr;
struct proc;
struct ifaddr;

int	 route_init __P((void));
void	 rtalloc __P((struct route *));
void	 rtalloc_ign __P((struct route *, u_long));
struct rtentry *
	 rtalloc1 __P((struct sockaddr *, int, u_long));
int	 rtinit __P((struct ifaddr *, int, int));
int	 rtioctl __P((u_long, caddr_t, struct proc *));
int	 rtredirect __P((struct sockaddr *, struct sockaddr *,
	    struct sockaddr *, int, struct sockaddr *, struct rtentry **));
int	 rtrequest __P((int, struct sockaddr *,
	    struct sockaddr *, struct sockaddr *, int, struct rtentry **));
struct ifaddr *ifa_ifwithindex __P((int flags, int index, struct sockaddr *dst, 
				    struct sockaddr *gate));
struct ifaddr *ifa_ifaddrValidate __P((void *pIfAddr, int index)); 
void rt_maskedcopy __P((struct sockaddr *src, struct sockaddr *dst, 
			struct sockaddr *netmask));
void ipRouteFree __P((struct rtentry * pRoute, BOOL inTable));

#include <route/ipRouteLib.h>
#endif /* _WRS_KERNEL */

#ifdef __cplusplus
}
#endif

#endif /* _NET_ROUTE_H_ */
